import datetime
import random

from django.db import transaction
from django.db.models import F
from rest_framework.decorators import action
from rest_framework.views import APIView
from rest_framework import generics
from utils import response_error, response_ok
from utils.custom_modelviewset import CustomModelViewSet
from apps.member.stores.serializers import StoreDetailSerializer
from apps.member.comment.models import Comment
from utils.exceptions import CustomError
from utils.permission import IsMemberUser
from utils.wechat_applet import WeChatApplet
from .vote.models import VoteActivity, VoteActivityApply
from .vote.serializers import VoteActivityApplyDetailSerializer
from .bargain.models import BargainActivity, BargainActivityApply, MemberBargainRecord
from .bargain.serializers import BargainActivitySerializer
from .models import Activity, ActivityCeleryTask, MemberActivity, CollectActivity
from .serializers import ActivityDetailSerializers, MemberActivitySerializers, ActivityCudSerializers, \
    ActivityListSerializers
from .filters import MemberActivityFilter, ActivityFilter
from .tasks import start_activity_task, end_activity_task


class ActivityListViewSet(generics.ListAPIView):
    queryset = Activity.objects.filter(delete=False)
    serializer_class = ActivityListSerializers

    def filter_queryset(self, queryset):
        f = ActivityFilter(self.request.GET, queryset=queryset)
        return f.qs


class MineCreateActivityListViewSet(generics.ListAPIView):
    queryset = Activity.objects.filter(delete=False)
    serializer_class = ActivityListSerializers

    def filter_queryset(self, queryset):
        queryset = queryset.filter(merchant=self.request.user.member)
        f = ActivityFilter(self.request.GET, queryset=queryset)
        return f.qs


class ActivityDetailViewSet(generics.RetrieveAPIView):
    queryset = Activity.objects.filter()
    serializer_class = ActivityDetailSerializers

    def retrieve(self, request, *args, **kwargs):
        instance = self.get_object()
        Activity.objects.filter(id=instance.id).update(brown_count=F('brown_count') + 1)
        serializer = self.get_serializer(instance)
        return response_ok(serializer.data)


class MineApplyActivityView(generics.ListAPIView):
    '''我报名的活动'''
    permission_classes = [IsMemberUser, ]
    queryset = MemberActivity.objects.filter()
    serializer_class = MemberActivitySerializers

    def filter_queryset(self, queryset):
        queryset = queryset.filter(member=self.request.user.member)
        f = MemberActivityFilter(self.request.GET, queryset=queryset)
        return f.qs


class ActivityViewSet(CustomModelViewSet):
    permission_classes = [IsMemberUser, ]
    queryset = Activity.objects.filter(delete=False)
    serializer_class = ActivityCudSerializers

    def create(self, request, *args, **kwargs):
        try:
            activity_type = request.data['activity_type']
            serializer = self.get_serializer(data=request.data)
            if serializer.is_valid(raise_exception=True):
                with transaction.atomic():
                    # 有时您会希望您的视图代码能够在保存实例时注入额外的数据。此额外数据可能包括当前用户,您可以通过在调用 .save() 时包含其他关键字参数来执行此操作
                    activity = serializer.save(merchant=request.user.member)
                    # 创建投票活动
                    if activity_type == Activity.VOTE:
                        vote = request.data['vote']
                        # 投票活动
                        vote_activity = VoteActivity.objects.create(activity=activity, vote_way=vote['vote_way'],
                                                                    vote_time=vote['vote_time'])
                    # 创建砍价活动
                    else:
                        bargain = request.data['bargain']
                        # 还剩优惠券数量
                        bargain['remain_count'] = bargain['coupon_count']
                        bargain_activity_ser = BargainActivitySerializer(data=bargain)
                        if bargain_activity_ser.is_valid(raise_exception=True):
                            bargain_activity_ser.save(activity=activity)

                    # 定时任务1 从预热 -->  开始
                    # 当前时间（2020-10-22 12:01:54+08:00） 获取时间戳（1603339314.0）、获得utc时间（2020-10-22 04:01:54）
                    start_task_time = datetime.datetime.utcfromtimestamp(activity.start_time.timestamp())
                    start_task_id = start_activity_task.apply_async(args=[activity.id], eta=start_task_time).id

                    end_task_time = datetime.datetime.utcfromtimestamp(activity.end_time.timestamp())
                    end_task_id = end_activity_task.apply_async(args=[activity.id], eta=end_task_time).id

                    ActivityCeleryTask.objects.create(activity=activity, start_task_id=start_task_id,
                                                      end_task_id=end_task_id)
                    return response_ok()
        except Exception as e:
            import traceback
            traceback.print_exc()
            return response_error(str(e))

    @action(methods=['get'], detail=True)
    def store_info(self, request, pk):
        # 活动的商铺信息
        try:
            activity = Activity.get_instance_by_id(pk)
            return response_ok(StoreDetailSerializer(activity.store, context={'request': self.request}).data)
        except CustomError as e:
            return response_error(e.get_error_msg())
        except Exception as e:
            return response_error(str(e))

    @action(methods=['get'], detail=True)
    def collect(self, request, pk):
        try:
            activity = Activity.get_instance_by_id(pk)
            with transaction.atomic():
                instance, operate = CollectActivity.objects.get_or_create(activity=activity, member=request.user.member)
            if operate:
                return response_ok('收藏成功')
            else:
                instance.delete()
                return response_ok('成功取消收藏')
        except CustomError as e:
            return response_error(e.get_error_msg())
        except Exception as e:
            return response_error(str(e))

    @action(methods=['post'], detail=True)
    def comment(self, request, pk):
        try:
            activity = Activity.get_instance_by_id(pk)
            content = request.data['content']
            # 微信敏感词校验
            WeChatApplet().wx_check_content(content)
            if not content:
                return response_ok('评论内容不能为空')
            with transaction.atomic():
                Comment.objects.create(member=request.user.member, content=content, activity=activity)
        except CustomError as e:
            return response_error(e.get_error_msg())
        except Exception as e:
            return response_error(str(e))
        return response_ok()
